/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hps.view;

import hps.model.Point;
import hps.model.Room;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JPanel;

/**
 *
 * @author $Author: schmidts.oli $
 * @version $Revision: 82 $
 * @date $Date: 2013-01-14 13:21:21 +0000 (Mon, 14 Jan 2013) $
 */
public class RoomDrawPanel extends JPanel implements Observer
{

    private Room room;
    private Point roomPos;
    private int singleFieldSize;
    //Speicher für Mausbewegung
    private java.awt.Point lastMousePosition;
    //Buffer fuer Zeichnen
    BufferedImage bufferImage;

    public RoomDrawPanel()
    {
        super();
        createRoom(25, 25);

        //Buffer zum Zeichnen
        bufferImage = null;

        //MouseListener zum speichern der MousePress position
        addMouseListener(new java.awt.event.MouseAdapter()
        {
            public void mousePressed(java.awt.event.MouseEvent evt)
            {
                lastMousePosition = evt.getPoint();
            }
        });

        //MouseMotionListener zum bewegen der Karte
        addMouseMotionListener(new java.awt.event.MouseMotionAdapter()
        {
            public void mouseDragged(java.awt.event.MouseEvent evt)
            {
                roomPos = new Point(roomPos.getX() + (evt.getX() - lastMousePosition.x), roomPos.getY() + (evt.getY() - lastMousePosition.y));
                lastMousePosition = evt.getPoint();
                paintComponent(getComponentGraphics(getGraphics()));
            }
        });

        addMouseWheelListener(
                new MouseWheelListener()
                {
                    @Override
                    public void mouseWheelMoved(java.awt.event.MouseWheelEvent evt)
                    {
                        if ((singleFieldSize - 2 * evt.getUnitsToScroll() > 5) && (singleFieldSize - 2 * evt.getUnitsToScroll() < 100))
                        {
                            singleFieldSize = singleFieldSize - 2 * evt.getUnitsToScroll();
                            paintComponent(getComponentGraphics(getGraphics()));
                        }
                    }
                });
    }

    /**
     * Überschreibt Methode, um Raum mitzumalen
     *
     * @param g
     */
    @Override
    public void paintComponent(Graphics g)
    {
        //ggf BufferImage erstellen
        if ((bufferImage == null) || (bufferImage.getHeight() != this.getHeight()) || (bufferImage.getWidth() != this.getWidth()))
        {

            bufferImage = GraphicsEnvironment.
                    getLocalGraphicsEnvironment().getDefaultScreenDevice().
                    getDefaultConfiguration().createCompatibleImage(this.getWidth(), this.getHeight());
            //bufferImage = new BufferedImage(this.getWidth()-10, this.getHeight()-10,BufferedImage.TYPE_4BYTE_ABGR);
        }

        Graphics newGraphics = bufferImage.getGraphics();

        super.paintComponent(newGraphics);
        getRoom().draw(newGraphics, roomPos, singleFieldSize);
        g.drawImage(bufferImage, 0, 0, null);
    }

    /**
     * Erstellt neuen Raum mit uebergebenen Dimensionen
     *
     * @param xDim
     * @param yDim
     */
    public void createRoom(int xDim, int yDim)
    {
        setRoom(new Room(xDim, yDim));
    }

    /**
     * @return the room
     */
    public Room getRoom()
    {
        return room;
    }

    /**
     * @param room the room to set
     */
    public void setRoom(Room room)
    {
        if (this.room != null)
        {
            this.room.deleteObservers();
        }
        roomPos = new Point(10, 10);
        singleFieldSize = 25;
        this.room = room;
        this.room.addObserver(this);
        try
        {
            paintComponent(getGraphics());
        }
        catch (IllegalArgumentException e)
        {
            System.err.println(e.getLocalizedMessage() + ":\n" + e.getStackTrace());
        }
    }

    /**
     * Gibt die Feldkoordinaten des Feldes zurück, das an position (relativ zu
     * Panelursprung) angezeigt wird
     *
     * @param position
     * @return Koordinaten des Feldes, (-1, -1) falls auserhab des Feldes
     */
    public Point getField(java.awt.Point position)
    {
        //Errechnen der Koordinaten
        Point rtrn = new Point((int) ((position.x - roomPos.getX()) / (float) singleFieldSize), (int) ((position.y - roomPos.getY()) / (float) singleFieldSize));
        //Pruefen der Position
        if ((rtrn.getX() < 0) || (rtrn.getX() >= room.getxDim()) || (rtrn.getY() < 0) || (rtrn.getY() >= room.getyDim()))
        {
            rtrn = new Point(-1, -1);
        }
        //Rueckgabe
        return rtrn;
    }

    @Override
    public void update(Observable o, Object arg)
    {
        paintComponent(getGraphics());
    }
}
